/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 *
 * $Rev: 19 $
 * $LastChangedDate: 2009-04-14 16:14:44 +0000 (Tue, 14 Apr 2009) $
 */

package Main;

import javax.microedition.lcdui.*;
import java.util.*;
//import Main.mMath.*;

/**
 * @author moreto
 */
public class ResultCanvas extends Canvas implements CommandListener {
    /**
     * constructor
     */
    private Calendar calendar = Calendar.getInstance();
    private int year;
    private int month;
    private int day;
    private int hour;
    private int minute;
    private int seconds;
    private int ia = 0;
    //private int tzoneOffset = 0;

    public ResultCanvas() {
     //   try {
	    // Set up this canvas to listen to command events
	    //setCommandListener(this);
	    // Add the Exit command
	    //addCommand(new Command("Exit", Command.EXIT, 1));
      //  } catch(Exception e) {
      //      e.printStackTrace();
     //   }
    }
    
    /**
     * paint method
     */
    public void paint(Graphics g) {

        int width = getWidth();
        int height = getHeight();

        // Filling the canvas with a black rectangle:
        g.fillRect(0, 0, width, height );
        g.setColor (255, 0, 0);

        Font font = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN,Font.SIZE_SMALL);
        g.setFont(font);

        returnObjetc data = calculateOrbits(width,height,ia);

        int moonRadius = 3;

        boolean namesPosFlag = true;
        int yt = 0;

        for (int i=0; i<4; i++){
            String xstr = String.valueOf(Math.ceil(data.X[i]));
            String ystr = String.valueOf(Math.ceil(data.Y[i]));
            String orbstr = String.valueOf(Math.ceil(data.Radius[i]));
            int indexX = xstr.indexOf(".");
            int indexY = ystr.indexOf(".");
            int indexR = orbstr.indexOf(".");

            String xstrOk = xstr.substring(0, indexX);
            String ystrOk = ystr.substring(0, indexY);
            String radiusOk = orbstr.substring(0,indexR);

            int x = Integer.parseInt(xstrOk);
            int y = Integer.parseInt(ystrOk);
            int radius = Integer.parseInt(radiusOk);

            g.fillArc (x - moonRadius, y - moonRadius, moonRadius*2, moonRadius*2,0,360);


            // Placing the text:
            if (namesPosFlag){
                yt = y + 5;
                namesPosFlag = false;
            }else{
                yt = y - 20;
                namesPosFlag = true;
            }
            if (x >= width/2){
                g.drawString(data.Names[i], x, yt, Graphics.TOP|Graphics.RIGHT);
            }else{
                g.drawString(data.Names[i], x, yt, Graphics.TOP|Graphics.LEFT);
            }

            // Drawing orbital paths:
            if (ia == 90){
                g.drawArc(width/2-radius, height/2-radius, 2 * radius, 2 * radius, 0, 360);
            }
        }

        // Jupiter:
        int js = 2*71398/(1880000 / (240/2));
        g.fillArc(width/2-js/2,height/2-js/2, js, js, 0, 360);
        String str1 = String.valueOf(hour)+":"+String.valueOf(minute)+":"+String.valueOf(seconds)+"h";
        String str2 = String.valueOf(day)+"/"+String.valueOf(month)+"/"+String.valueOf(year);
        g.drawString(str1 + " (UT)", width/2, 0, Graphics.TOP|Graphics.HCENTER);
        g.drawString(str2, width/2, height, Graphics.BOTTOM|Graphics.HCENTER);
    }

    /*
     * Set Method.
     */

    public void updateCanvas(){
        repaint();
    }

    /*
     * This is the method that calculate the orbits.
     */
    private returnObjetc calculateOrbits(int width, int height, int ia){
        // Initial definitions:

        double scale = 1880000 / (width/2);
        double P = Math.PI / 180;
        int RP = 71398;
        int JIK = 0;

        double U[] = {0,0,0,0};
        double T[] = {0,0,0,0};
        double SMA[] = {421600, 670900, 1070000, 1880000};
        double E[] = {0, 0, .001, .01};
        String N[] = {"Io", "Eu", "Ga", "Ca"};
        int IA[] = {ia, ia, ia, ia};
        
        // Results:
        double X[] = {0,0,0,0};
        double Y[] = {0,0,0,0};
        double orbitRadius[] = {0,0,0,0};

        // *********************** JULIAN DAY *********************************

        JIK = JIK + 1;
        int GGG = 1;
        if (year <= 1585){
            GGG = 0;
        }
        double F = (hour / 24.0) + (minute / (24.0 * 60.0)) - 0.5;
        double JD = -1 * Math.floor(7 * (Math.floor((month + 9) / 12) + year) / 4);
        int S;
        if ((month - 9) > 0){
            S = 1;
        }else if ((month - 9) == 0){
            S = 0;
        }else{
            S = -1;
        }

        int A = Math.abs(month - 9);
        double J1 = Math.floor(year + S * Math.floor(A / 7));
        J1 = -1 * Math.floor((Math.floor(J1 / 100) + 1) * 3 / 4);
        JD = JD + Math.floor(275 * month / 9) + day + (GGG * J1);
        JD = JD + 1721027 + 2 * GGG + 367 * year; // Julian Day
        //System.out.println("Julian day: " + String.valueOf(JD));
        // ********************** FIND MOON ANGLES *************************
        double NN = JD - 2415020 + F;
        double MT = (358.476 + .9856003 * NN) * P;
        double MJ = (225.328 + .0830853 * NN) * P;
        double JJ = 221.647 + .9025179 * NN;
        double VT = 1.92 * Math.sin(MT) + .02 * Math.sin(2 * MT);
        double VJ = 5.55 * Math.sin(MJ) + .17 * Math.sin(2 * MJ);
        double K = (JJ + VT - VJ) * P;
        double DT = Math.sqrt(28.07 - 10.406 * Math.cos(K));
        double Z = Math.sin(K) / DT;
        double II = mMath.atan(Z / Math.sqrt(1 - Z * Z));
        II = II / P;
        F = (NN - DT / 173);
        double F1 = II - VJ;
        U[0] = 84.5506 + 203.405863 * F + F1;// Theta Coordinates of Orbits
        U[1] = 41.5015 + 101.2916323 * F + F1;
        U[2] = 109.977 + 50.2345169 * F + F1;
        U[3] = 176.3586 + 21.4879802 * F + F1;
        
        // **********Calculating the positions on the screen ****************
        for (int i=0; i<4; i++){
            if (ia == 90){
                orbitRadius[i] = SMA[i]/scale;
            }
            
            U[i] = ((U[i] / 360) - Math.floor(U[i] / 360)) * 360;
            T[i] = U[i] * P + Math.PI;
            double R = SMA[i] * (1 - (E[i]*E[i])) / (1 + (E[i] * Math.cos(T[i])));
            X[i] = (width / 2) + (R * Math.sin(T[i]) / scale);
            Y[i] = (height / 2) + Math.floor((R * Math.cos(T[i]) * Math.sin(IA[i] * P) / scale) + .5);
        }
       
        //System.out.println("atan: " + String.valueOf(mMath.atan(Math.PI/2)));

        returnObjetc out = new returnObjetc();
        out.X = X;
        out.Y = Y;
        out.Radius = orbitRadius;
        out.Names = N;
        
        return out;
    }

    /*
     * Setter method to date used to plot.
     */
    public void setDate(long d){
        // Converting the date in milliseconds to a date object and
        // creating a calendar object.
        calendar.setTime(new Date(d));

        TimeZone tzone = TimeZone.getTimeZone("GMT");
        //tzoneOffset = tzone.getRawOffset();

        calendar.setTimeZone(tzone);

        year = calendar.get(calendar.YEAR);
        month = calendar.get(calendar.MONTH) + 1;
        day = calendar.get(calendar.DAY_OF_MONTH);
        hour = calendar.get(calendar.HOUR_OF_DAY);
        minute = calendar.get(calendar.MINUTE);
        seconds = calendar.get(calendar.SECOND);
    }
    /**
     * Called when a key is pressed.
     */
    protected  void keyPressed(int keyCode) {
        if (keyCode == KEY_NUM5){
            if (ia == 0){
                ia =  90;
            }else{
                ia = 0;
            }
        }
        repaint();
    }
    
    /**
     * Called when a key is released.
     */
    protected  void keyReleased(int keyCode) {
    }

    /**
     * Called when a key is repeated (held down).
     */
    protected  void keyRepeated(int keyCode) {
    }
    
    /**
     * Called when the pointer is dragged.
     */
    protected  void pointerDragged(int x, int y) {
    }

    /**
     * Called when the pointer is pressed.
     */
    protected  void pointerPressed(int x, int y) {
    }

    /**
     * Called when the pointer is released.
     */
    protected  void pointerReleased(int x, int y) {
    }
    
    /**
     * Called when action should be handled
     */
    public void commandAction(Command command, Displayable displayable) {
    }

}

class returnObjetc{
    double[] X;
    double[] Y;
    double[] Radius;
    String[] Names;
}